#include "nv.h"

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <hi_types_base.h>
#include "ohos_init.h"
#include "cmsis_os2.h"

#include "hi_nvm.h"
#include <hi_nv.h>
#include <hi_flash.h>
#include <hi_partition_table.h>

// memspy_s 要用到
#include "lwip/ip_addr.h"
#include "lwip/netifapi.h"
#include "lwip/sockets.h"

#include "list.h"

//KV
// #include "kvstore_common.h"

extern unsigned char ssid[50];
extern unsigned char passwd[50];
extern unsigned int g_user_num;
extern struct scancard_time ScanCard_Time;


void NV_Test(void)
{
    wal_cfg_ssid_my nv;
    int ret;

    int ssid_len = strlen((const char *)&ssid[0]);
    int passwd_len = strlen((const char *)&passwd[0]);

    memset(&nv, 0, sizeof(wal_cfg_ssid_my));
    memcpy_s(&nv.ssid[0], sizeof(wal_cfg_ssid_my), ssid, ssid_len);
    memcpy_s(&nv.passwd[0], sizeof(wal_cfg_ssid_my), passwd, passwd_len);

    ret = hi_factory_nv_write(NV_ID, &nv, sizeof(wal_cfg_ssid_my), 0);
    if (ret != 0) {
        printf("hi_factory_nv_write fail ret=%x\r\n", ret);
    }
    /* 再次读取写入的 NV 值 */
    ret = hi_factory_nv_read(NV_ID, &nv, sizeof(wal_cfg_ssid_my), 0);
    if (ret != 0) {
        printf("hi_factory_nv_read fail ret=%x\r\n", ret);
    }
    printf("nv read : %d, ssid :[%s] psswd [%s]\r\n",ret, nv.ssid, nv.passwd);
}


/* ---------------------------------------- 以下是临时的 ---------------------------------------- */
/* ------------------------------------- 以下是临时的(成功) ------------------------------------- */
/* ---------------------------------------- 以下是临时的 ---------------------------------------- */

extern bool sys_Running_First;
#include <hi_flash.h>
#include <hi_task.h>
#include <hi_stdlib.h>
#include <hi_watchdog.h>
#include <hi_early_debug.h>
#include <hi_time.h>
void Flash_Test(void)
{
    hi_u8 g_tf_pdata[TEST_SIZE] = "1234567890";
    hi_u8 g_tf_pdata_back[TEST_SIZE] = {0};
    hi_u32 ret;
    hi_bool do_erase = HI_FALSE; /* 是否擦除Flash */

    if(sys_Running_First) //下完程序第一次运行
	{
		/* 写 Flash */
        // 第一次写所以不需要擦
        ret = hi_flash_write(TEST_FLASH_OFFSET, TEST_SIZE, &g_tf_pdata[0], do_erase);
        if (ret != HI_ERR_SUCCESS) {
            /* 错误处理 */
            printf("hi_flash_write failed, ret = %d.\r\n", ret);
        }

		printf("\r\n<--- First Run System ---> \r\n\r\n");
		sys_Running_First = 0;
	}

    memset_s(g_tf_pdata_back, TEST_SIZE, 0, TEST_SIZE); /* 清空BUF */

    /* 读Flash */
    ret = hi_flash_read(TEST_FLASH_OFFSET, TEST_SIZE, g_tf_pdata_back);
    if (ret != HI_ERR_SUCCESS) {
        /* 错误处理 */
        printf("hi_flash_read failed, ret = %d.\r\n", ret);
    }

    //重新擦除后，Flash的数据全部变为 FFh 
    printf("(hi_flash_read)test data : \r\n");
    for(int i=0;i<TEST_SIZE;i++)
    {
        printf("%X ", g_tf_pdata_back[i]);

        // g_tf_pdata[20+i] = i;
    }
    printf("\r\n");


    do_erase = HI_TRUE;
    g_tf_pdata[5] = 0x52;
    
    // 每次重新写入相同的地址需要提前擦除
    ret = hi_flash_write(TEST_FLASH_OFFSET, TEST_SIZE, &g_tf_pdata[0], do_erase);
    if (ret != HI_ERR_SUCCESS) {
        /* 错误处理 */
        printf("hi_flash_write failed, ret = %d.\r\n", ret);
    }
}


/* ---------------------------------------- 以下是新的 ---------------------------------------- */
/* ------------------------------------- 以下是新的(测试) ------------------------------------- */
/* ---------------------------------------- 以下是新的 ---------------------------------------- */
void Flash_Write(const hi_u32 flash_offset, LinkList L, hi_u8 user_num, hi_bool do_erase)
{
    hi_u32 ret;
    unsigned char i, j;
    LinkList P;
    hi_u8 pdata[FLASH_USERINFO_SIZE] = {0};

    do_erase = HI_FALSE; /* 是否擦除Flash: 默认不擦除，适用于烧录后第一次上电 */

    P = L->next;

    for(i=0; i<user_num; i++)
    {
        memset_s(&pdata[0], FLASH_USERINFO_SIZE, 0, FLASH_USERINFO_SIZE);

        pdata[0] = P->data.userid >> 24;
        pdata[1] = P->data.userid >> 16;
        pdata[2] = P->data.userid >> 8;
        pdata[3] = P->data.userid;

        pdata[4] = P->data.permission;
        pdata[5] = P->data.permission_last;

        pdata[6] = P->data.permission_time_is_forever;
        pdata[7] = P->data.permission_time_hours;
        pdata[8] = P->data.permission_time_minutes;
        pdata[9] = P->data.permission_time_seconds;

        pdata[10] = P->data.scancard_time_is_same;
        pdata[11] = P->data.morning_time_hours;
        pdata[12] = P->data.morning_time_minutes;
        pdata[13] = P->data.morning_time_seconds;
        pdata[14] = P->data.afternoon_time_hours;
        pdata[15] = P->data.afternoon_time_minutes;
        pdata[16] = P->data.afternoon_time_seconds;

        for(j=0; j<NAME_BYTE_LEN; j++)
        {
            pdata[17+j] = P->data.name[j];
        }

        /* 写 Flash */
        ret = hi_flash_write(flash_offset + FLASH_USERINFO_SIZE*i, FLASH_USERINFO_SIZE, &pdata[0], do_erase);
        if (ret != HI_ERR_SUCCESS) {
            /* 错误处理 */
            printf("hi_flash_write -- Flash_Write failed, ret = %d.\r\n", ret);
        }

        P = P->next;
    }

    ret = hi_flash_write(FLASH_USERINFO_USER_NUM, 1, &user_num, do_erase);
    if (ret != HI_ERR_SUCCESS) {
        /* 错误处理 */
        printf("hi_flash_write -- Flash_Write_UserNum failed, ret = %d.\r\n", ret);
    }
}

void Flash_Read(const hi_u32 flash_offset, LinkList L, hi_u8 *user_num)
{
    hi_u32 ret;
    unsigned char i, j;
    // LinkList P;
    UserInfo read_user; //用来临时存储从Flash中读取的用户信息
    hi_u8 pdata[FLASH_USERINFO_SIZE] = {0};
    hi_u8 user_num_tmp;

    ret = hi_flash_read(FLASH_USERINFO_USER_NUM, 1, &user_num_tmp);
    if (ret != HI_ERR_SUCCESS) {
        /* 错误处理 */
        printf("hi_flash_read -- Flash_Read_UserNum failed, ret = %d.\r\n", ret);
    }
    *user_num = user_num_tmp;

    // P = L->next; //擦除后不是第一次上电，创建数据库头结点后第一次调用 RC522_Database 的 next 会是空，所以会报错：主控板一直复位，异常信息是:[0x7]，表示指针有问题。

    for(i=0; i<user_num_tmp; i++)
    {
        memset_s(&pdata[0], FLASH_USERINFO_SIZE, 0, FLASH_USERINFO_SIZE);
        
        /* 读Flash */
        ret = hi_flash_read(flash_offset + FLASH_USERINFO_SIZE*i, FLASH_USERINFO_SIZE, &pdata[0]);
        if (ret != HI_ERR_SUCCESS) {
            /* 错误处理 */
            printf("hi_flash_read -- Flash_Read failed, ret = %d.\r\n", ret);
        }

        // printf("\r\npdata[%d] = \r\n", i+1);
        // for(j=0; j<FLASH_USERINFO_SIZE; j++)
        // {
        //     printf("%X ", pdata[j]);
        // }
        // printf("\r\n\r\n");

        // *(&P->data.userid) = ((unsigned int)pdata[0]<<24) | ((unsigned int)pdata[1]<<16) | ((unsigned int)pdata[2]<<8) | ((unsigned int)pdata[3]);
        read_user.userid = ((unsigned int)pdata[0]<<24) | ((unsigned int)pdata[1]<<16) | ((unsigned int)pdata[2]<<8) | ((unsigned int)pdata[3]);
        // printf("------ debug userid ------\r\n");

        // P->data.permission = pdata[4];
        read_user.permission = pdata[4];
        // printf("------ debug permission ------\r\n");
        // P->data.permission_last = pdata[5];
        read_user.permission_last = pdata[5];
        // printf("------ debug permission_last ------\r\n");

        // P->data.permission_time_is_forever = pdata[6];
        read_user.permission_time_is_forever = pdata[6];
        // printf("------ debug permission_time_is_forever ------\r\n");
        // P->data.permission_time_hours = pdata[7];
        read_user.permission_time_hours = pdata[7];
        // printf("------ debug permission_time_hours ------\r\n");
        // P->data.permission_time_minutes = pdata[8];
        read_user.permission_time_minutes = pdata[8];
        // printf("------ debug permission_time_minutes ------\r\n");
        // P->data.permission_time_seconds = pdata[9];
        read_user.permission_time_seconds = pdata[9];
        // printf("------ debug permission_time_seconds ------\r\n");

        // P->data.scancard_time_is_same = pdata[10];
        read_user.scancard_time_is_same = pdata[10];
        // printf("------ debug scancard_time_is_same ------\r\n");
        read_user.morning_time_hours = pdata[11];
        // printf("------ debug morning_time_hours ------\r\n");
        read_user.morning_time_minutes = pdata[12];
        // printf("------ debug morning_time_minutes ------\r\n");
        read_user.morning_time_seconds = pdata[13];
        // printf("------ debug morning_time_seconds ------\r\n");
        read_user.afternoon_time_hours = pdata[14];
        // printf("------ debug afternoon_time_hours ------\r\n");
        read_user.afternoon_time_minutes = pdata[15];
        // printf("------ debug afternoon_time_minutes ------\r\n");
        read_user.afternoon_time_seconds = pdata[16];
        // printf("------ debug afternoon_time_seconds ------\r\n");

        for(j=0; j<NAME_BYTE_LEN; j++)
        {
            read_user.name[j] = pdata[17+j];
        }
        // printf("------ debug for ------\r\n");

        Insert(&read_user, L);

        // P = P->next;
        // printf("------ debug P = P->next ------\r\n");
    }
}

void Flash_Write_Scancard(const hi_u32 flash_offset, hi_bool do_erase)
{
    hi_u32 ret;
    unsigned char i;
    unsigned char time[6] = {0};

    do_erase = HI_FALSE; /* 是否擦除Flash: 默认不擦除，适用于烧录后第一次上电 */

    for(i=0; i<6; i++)
    {
        time[0] = ScanCard_Time.morning_time_hours;
        time[1] = ScanCard_Time.morning_time_minutes;
        time[2] = ScanCard_Time.morning_time_seconds;
        time[3] = ScanCard_Time.afternoon_time_hours;
        time[4] = ScanCard_Time.afternoon_time_minutes;
        time[5] = ScanCard_Time.afternoon_time_seconds;
    }

    ret = hi_flash_write(FLASH_SCANCARD_TIME, 6, &time[0], do_erase);
    if (ret != HI_ERR_SUCCESS) {
        /* 错误处理 */
        printf("hi_flash_write -- Flash_Writ_Scancard failed, ret = %d.\r\n", ret);
    }
}

void Flash_Read_Scancard(const hi_u32 flash_offset)
{
    hi_u32 ret;
    unsigned char i;
    unsigned char time[6] = {0};

    ret = hi_flash_read(FLASH_SCANCARD_TIME, 6, &time[0]);
    if (ret != HI_ERR_SUCCESS) {
        /* 错误处理 */
        printf("hi_flash_read -- Flash_Read_Scancard failed, ret = %d.\r\n", ret);
    }

    for(i=0; i<6; i++)
    {
        ScanCard_Time.morning_time_hours = time[0];
        ScanCard_Time.morning_time_minutes = time[1];
        ScanCard_Time.morning_time_seconds = time[2];
        ScanCard_Time.afternoon_time_hours = time[3];
        ScanCard_Time.afternoon_time_minutes = time[4];
        ScanCard_Time.afternoon_time_seconds = time[5];
    }
}
